<?php
/**
 * Created by PhpStorm.
 * User: wo
 * Date: 2017/7/17
 * Time: 14:26
 */

namespace app\admin\controller;
use think\Db;
use app\index\controller\Alistock;
use app\index\controller\Home;

set_time_limit(0);

const DATA_SECONDS = 10;    //////获取15秒以内的数据
class Jobs
{
    //批量获取在线股票的实时数据，存到数据库
    public function getStockDataToDb(){
        file_put_contents("llog.txt", $this->getIP()." , getStockDataToDb, ". date("Y-m-d H:i:s")."\r\n" , FILE_APPEND);

        $t1 = time();
        $tm = time() - DATA_SECONDS;
        $stockList = Db::table("xh_stock_visit_record")->field("distinct(code)")->where("createTimeStamp > $tm")->select();
        $stocks = "";
        foreach($stockList as $k => $v){
            if($stocks != ''){
                $stocks .= ",";
            }
            $stocks .= $v['code'];
        }

        $stockMap = (new Alistock())->batch_real_stockinfo_full($stocks);
        //print_r($stockMap);
        foreach($stockMap as $k => $v){
            //print_r($v);
            $data = array();
            $data['code'] = $k;
            $data['detail'] = json_encode($v, JSON_UNESCAPED_UNICODE);
            $data['createTime'] = date("Y-m-d H:i:s");
            $data['createTimeStamp'] = time();

            $ret = Db::table("xh_online_stock_detail")->insertGetId($data);
            echo ($ret."<br/>");
        }

        $t2 = time();
        echo "t2-t1=".($t2 - $t1);
        //print_r($this->object2array($stockMap));

    }

    function object2array_(&$object) {
        $object =  json_decode( json_encode( $object),true);
        return  $object;
    }


    //获取股票实时价格，自动平仓 (每秒运行一次)
    public function pingCang(){
        file_put_contents("llog.txt", $this->getIP()." , pingCang, ". date("Y-m-d H:i:s")."\r\n" , FILE_APPEND);

        $t1 = time();

        $res = Db::table("xh_stock_order")
            ->where("status=1 and isFreetrial=0")
            ->field("distinct(stockCode)")
            ->select();
        $stocks = ""; //上证指数 深证成指 创业板指
        foreach($res as $k=>$v){
            if($stocks != ""){
                $stocks .= ",";
            }
            $stocks .= $v['stockCode'];
        }
        $stockMap = (new Alistock())->batch_real_stockinfo_full($stocks);

        $orderList = Db::table("xh_stock_order")
            ->where("status=1 and isFreetrial=0")
            ->select();
        foreach($orderList as $k=>$v){
            global $orderId, $liquidation;
            $orderId = $v['id'];
            $surplus = $v['surplus']; //止盈线
            $loss = $v['loss'];//止损线
            $stockDetail = $stockMap[$v['stockCode']];

            $diff_rate = $stockDetail->diff_rate ;//涨跌幅
            if($diff_rate <= -9.95){//股票跌停则不允许卖出
                echo $v['stockCode']."跌停<br/>";
                continue;
            }
            $nowPrice = $stockDetail->nowPrice ;   //实时价格
            if($nowPrice <= 0){
                continue;
            }

            $profit = ((float)$nowPrice - (float)$v['dealPrice']) * $v['dealQuantity'] * 100; //交易盈亏
            $profit = round($profit, 2);

            // 设置客户订单实时盈亏
            Db::table("xh_stock_order")->where('id', $v['id'])->setField('current_profit', $profit);

            //如果盈亏大于止盈线或小于止损线，则即时强制平仓
            $liquidation = -1; //0用户自己卖出; 1后台手动平仓；2超过止损线自动平仓；3超过止盈线自动平仓
            if($profit > $surplus){
                $liquidation = 3;
            }else if($profit < $loss){
                $liquidation = 2;
            }
            echo "diff_rate=$diff_rate % , orderId = $orderId, profit = $profit, surplus = $surplus, loss=$loss <br/>";

            //访问后台函数的权限
            define('UID', 1);
            session('user_auth.uid', 1);
            if($liquidation == 2 || $liquidation == 3){
                Db::transaction(function(){
                    global $orderId, $liquidation;
                    //echo "orderId=$orderId, liquidation=$liquidation";
                    (new Order())->stock_sell_do($orderId, $liquidation);
                    Db::commit();
                });
                //(new Order())->stock_sell_do($orderId, $liquidation);
            }
        }

        $t2 = time();
        echo "t2-t1=".($t2 - $t1)."<br/>";
    }

    //获取股票实时价格，判断亏损额大于递延条件则不允许递延（每天结束交易时运行一次）
    public function noDelay(){
        file_put_contents("llog.txt", $this->getIP()." , noDelay, ". date("Y-m-d H:i:s")."\r\n" , FILE_APPEND);

        if(date("H:i:s") <= "15:00:00"){
            die("交易时间不能调用此接口");
        }
        $res = Db::table("xh_stock_order")
            ->where("status=1 and isFreetrial=0")
            ->field("distinct(stockCode)")
            ->select();
        $stocks = ""; //上证指数 深证成指 创业板指
        foreach($res as $k=>$v){
            if($stocks != ""){
                $stocks .= ",";
            }
            $stocks .= $v['stockCode'];
        }
        $stockMap = (new Alistock())->batch_real_stockinfo_full($stocks);

        $orderList = Db::table("xh_stock_order")
            ->where("status=1 and isFreetrial=0")
            ->select();

        foreach($orderList as $i=>$v){
            global $orderId ;
            $orderId = $v['id'];
            $delayLine = $v['delayLine'];//止损线
            $stockDetail = $stockMap[$v['stockCode']];

            $diff_rate = $stockDetail->diff_rate ;//涨跌幅
            if($diff_rate <= -9.95){//股票跌停则不允许卖出
                echo $v['stockCode']."跌停<br/>";
                continue;
            }
            $nowPrice = $stockDetail->nowPrice;
            if($nowPrice <= 0){
                continue;
            }
            //echo "diff_rate=$diff_rate, nowPrice=$nowPrice <br/>";
            $profit = ((float)$nowPrice - (float)$v['dealPrice']) * $v['dealQuantity'] * 100; //交易盈亏
            $profit = round($profit, 2);
            if( $profit < -abs($delayLine) ){
                echo "orderId=$orderId, profit=$profit, delayLine=$delayLine <br/>";
                Db::transaction(function(){
                    global $orderId;
                    (new Order())->stock_sell_do($orderId, 4); //4 收盘时亏损额大于递延条件而自动平仓
                    Db::commit();
                });
            }
        }
    }

    //计算递延天数和递延费 每天凌晨运行一次
    public function delayDays(){
        file_put_contents("llog.txt", $this->getIP()." , delayDays, ". date("Y-m-d H:i:s")."\r\n" , FILE_APPEND);

        Db::transaction(function(){
            $t1 = time();
            require_once (dirname(__FILE__)."/../../index/controller/Home.php");
            $delayFee = \app\index\controller\getSysParamsByKey("delayFee");
            if(!is_numeric($delayFee)|| $delayFee <= 0) {
                die("递延费({$delayFee})不正确");
            }

            //获取交易列表
            $orderList = Db::table("xh_stock_order")
                ->where("status=1 and isFreetrial=0 and TO_DAYS(now()) - TO_DAYS(createTime)  > 0 ")
                ->select();
            $hList = Db::table("xh_holiday")->field("day")->select();

            foreach($orderList as $k=>$v){
                $orderId = $v['id'];
                $memberId = $v['memberId'];
                $dealAmount = $v['dealAmount'];
                $createTime = $v['createTime'];
                $workDays = $this->getWorkdaysCount($createTime, $orderId, $memberId, $delayFee * $dealAmount, $hList);
                $delayDays = $workDays;
                if($delayDays < 0){
                    $delayDays = 0;
                }
                if($delayDays > 0) {
                    $delayFeeSum = 0;
                    if($delayDays > 2){
                        $delayFeeSum = ($delayDays-2) * $delayFee * $dealAmount;
                    }
                    $sql = "update xh_stock_order set delayDays = $delayDays, delayFeeSum = $delayFeeSum where id=$orderId ";
                    Db::execute($sql);
                }
            }

            $t2=time();
            echo "time=".($t2 - $t1);
        });
    }

    public function ff(){

    }
    //每天凌晨执行，清数据库。
     public function clearstock(){
       
        $sql='delete from xh_online_stock_detail';
        $ret=Db::query($sql);

        $sql2='delete from xh_online_stock_KLine';
        $ret=Db::query($sql2);

        $sql3='delete from xh_online_stock_timeline';
        $ret=Db::query($sql3);

        $sql4='delete from xh_stock_visit_record ';
        $ret=Db::query($sql4);

    }
    function getWorkdaysCount ($start_date, $orderId, $memberId, $delayFee, $hList=null )
    {
        $t_start = strtotime($start_date);
        if(!$t_start){
            die("时间格式不对");
        }

        //从数据库读取节假日列表
        if(!$hList || count($hList) <= 0){
            $hList = Db::table("xh_holiday")->field("day")->select();
        }

        $days = 0;
        $i = 0;
        $nowTime = strtotime(date("Y-m-d ")."23:59:59");
        while( $t_start + 3600*24*$i <  $nowTime)
        {
            $timer = $t_start + 3600*24*$i;
            $num= date("N", $timer);
            if($num >= 1 and $num <= 5)
            {
                $timerDate = date("Y-m-d", $timer);
                //判断是否是节假日
                $isHoliday = false;
                foreach($hList as $k=>$v){
                    if($timerDate == $v['day']){
                        $isHoliday = true;
                        break;
                    }
                }
                if(!$isHoliday){ //非周末以及非节假日，则天数加1
                    $days++;
                    //如果days大于2，则添加递延费记录
                    if($days > 2 && !Db::table("xh_day_delayfee")->where("day='$timerDate' and orderId=$orderId")->find()){

                        $member = Db::table("xh_member")->field("username,mobile,usableSum")->where("id=$memberId")->find();
                        $usableSum = $member['usableSum'];
                        // if($usableSum >= $delayFee){//如果可用余额大于即将扣除的递延费
                            $data=array();
                            $data['day'] = $timerDate;
                            $data['memberId'] = $memberId;
                            $data['orderId'] = $orderId;
                            $data['delayFee'] = $delayFee;
                            Db::table("xh_day_delayfee")->insertGetId($data);//增加递延记录

                            //扣除余额
                            Db::table("xh_member")->where("id=$memberId")->setInc("usableSum", -$delayFee);
                            //添加资金记录
                            $data=array();
                            $data['memberId'] = $memberId;
                            $data['flow'] = 2;
                            $data['amount'] = $delayFee;
                            $data['usableSum'] = $usableSum - $delayFee;
                            $data['remarks'] = "扣除{$timerDate}递延费{$delayFee}元(订单号:$orderId)";
                            $data['createTime'] = date("Y-m-d H:i:s");
                            Db::table("xh_member_fundrecord")->insertGetId($data);

                        // }else{//如果余额不足  添加系统消息
                        //     $msg = "用户".$member['username']."(手机号为".$member['mobile'].")余额{$usableSum}元，扣除{$timerDate}的递延费{$delayFee}元失败(订单号:$orderId)";
                        //     Db::table("xh_note_msg")->insertGetId(array('message'=>$msg, 'createTime'=>date("Y-m-d H:i:s")));
                        // }

                    }
                }

            }
            $i++;
        }

        return $days;
    }


    function getIP() {
        if (getenv('HTTP_CLIENT_IP')) {
            $ip = getenv('HTTP_CLIENT_IP');
        }
        elseif (getenv('HTTP_X_FORWARDED_FOR')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        }
        elseif (getenv('HTTP_X_FORWARDED')) {
            $ip = getenv('HTTP_X_FORWARDED');
        }
        elseif (getenv('HTTP_FORWARDED_FOR')) {
            $ip = getenv('HTTP_FORWARDED_FOR');

        }
        elseif (getenv('HTTP_FORWARDED')) {
            $ip = getenv('HTTP_FORWARDED');
        }
        else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return $ip;
    }

}